/*******************************************************************************
 * Copyright (c) 2004, 2005 Elias Volanakis and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Elias Volanakis - initial API and implementation
 *******************************************************************************/
package edu.ccut.saturn.studio.wfg.command;

import java.util.Iterator;

import org.eclipse.gef.commands.Command;

import edu.ccut.saturn.studio.wfg.model.Connection;
import edu.ccut.saturn.studio.wfg.model.Shape;

public class ConnectionReconnectCommand extends Command {

	private static final String RENAME_COMMAND_MOVE_CONNECTION_ENDPOINT = "move connection endpoint";
	private static final String RENAME_COMMAND_MOVE_CONNECTION_STARTPOINT = "move connection startpoint";
	private static final String RECONNECTION_COMMAND_SHOULD_NOT_HAPPEN = "Should not happen";
	private Connection connection;
	private Shape newSource;
	private Shape newTarget;
	private final Shape oldSource;
	private final Shape oldTarget;
	
	public ConnectionReconnectCommand(Connection conn) {
		if (conn == null) {
			throw new IllegalArgumentException();
		}
		this.connection = conn;
		this.oldSource = conn.getSource();
		this.oldTarget = conn.getTarget();
	}
	
	public boolean canExecute() {
		if (newSource != null) {
			return checkSourceReconnection();
		} else if (newTarget != null) {
			return checkTargetReconnection();
		}
		return false;
	}
	
	private boolean checkSourceReconnection() {
		if (newSource.equals(oldTarget)) {
			return false;
		}
		for (Iterator<Connection> iter = newSource.getSourceConnections().iterator(); iter.hasNext();) {
			Connection conn = (Connection) iter.next();
			if (conn.getTarget().equals(oldTarget) &&  !conn.equals(connection)) {
				return false;
			}
		}
		return true;
	}
	
	private boolean checkTargetReconnection() {
		if (newTarget.equals(oldSource)) {
			return false;
		}
		for (Iterator<Connection> iter = newTarget.getTargetConnections().iterator(); iter.hasNext();) {
			Connection conn = (Connection) iter.next();
			if (conn.getSource().equals(oldSource) && !conn.equals(connection)) {
				return false;
			}
		}
		return true;
	}
	
	public void execute() {
		if (newSource != null) {
			connection.reconnect(newSource, oldTarget);
//			connection.setLineName("");
		} else if (newTarget != null) {
			connection.reconnect(oldSource, newTarget);
//			connection.setLineName("");
		} else {
			throw new IllegalStateException(RECONNECTION_COMMAND_SHOULD_NOT_HAPPEN);
		}
	}
	
	public void setNewSource(Shape connectionSource) {
		if (connectionSource == null) {
			throw new IllegalArgumentException();
		}
		setLabel(RENAME_COMMAND_MOVE_CONNECTION_STARTPOINT);
		newSource = connectionSource;
		newTarget = null;
	}
	
	public void setNewTarget(Shape connectionTarget) {
		if (connectionTarget == null) {
			throw new IllegalArgumentException();
		}
		setLabel(RENAME_COMMAND_MOVE_CONNECTION_ENDPOINT);
		newSource = null;
		newTarget = connectionTarget;
	}
	
	public void undo() {
		connection.reconnect(oldSource, oldTarget);
	}
}
